home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v16n10 / embedcp.exe / CODE.EXE / COMF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-28  |  6.9 KB  |  239 lines

  1. /* Object module converter (comf)                                       */
  2. /* ==============================                                       */
  3. /*                                                                      */
  4. /* Copyright (c) 1991, Stuart G. Phillips.  All rights reserved.        */
  5. /*                                                                      */
  6. /* Permission is granted for non-commercial use of this software.       */
  7. /* You are expressly prohibited from selling this software in any form, */
  8. /* distributing it with another product, or removing this notice.       */
  9. /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR       */
  10. /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED       */
  11. /* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR           */
  12. /* PURPOSE.                                                             */
  13. /*                                                                      */
  14. /* This program accepts as input a program file in Microsoft .EXE       */
  15. /* format and relocates it for loading into an MIO IO processor.        */
  16. /* A new header is written that identifies the file as an MIO .LOD file */
  17. /* and provides the initial entry point for the down load module.       */
  18. /* file.                                                                */
  19. /*                                                                      */
  20. /*                                                                      */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <fcntl.h>
  26. #include <sys\stat.h>
  27. #include <io.h>
  28. #include "objform.h"
  29.  
  30. #define BUFSIZE 1024
  31.  
  32. /* Local procedure declarations */
  33.  
  34. static void read_blk(FILE *,char *,int);
  35. static void write_blk(FILE *,char *,int);
  36. static int sort_rel(const void *,const void *);
  37.  
  38. /* Static data declarations */
  39.  
  40. static char in_buf[BUFSIZE];
  41. static char out_buf[BUFSIZE];
  42. static char buffer[BUFSIZE];
  43.  
  44.  
  45. void usage()
  46. {
  47.     printf("Usage: comf infile outfile [base]\n");
  48.     printf("       base = code base for relocation (default = 0)\n");
  49. }
  50.  
  51.  
  52.  
  53. void main(argc,argv)
  54. int argc;
  55. char *argv[];
  56. {
  57.     struct EXEHDR *exe_hdr;
  58.     struct LODHDR *lod_hdr;
  59.     struct RELITEM *rel_table = (struct RELITEM *)
  60.                     calloc(10000,sizeof(struct RELITEM));
  61.     struct RELITEM rel;
  62.     FILE *infile,*infile2,*outfile;
  63.     unsigned short nrel, rel_cnt, base_cs, count, i;
  64.     long position, offset, image_size;
  65.     int fd;
  66.  
  67.     if (argc < 3) {
  68.         usage();
  69.         exit(1);
  70.     }
  71.  
  72.     if ((infile = fopen(argv[1],"rb")) == NULL) {
  73.         printf ("Cannot open input file - %s\n", argv[1]);
  74.         exit(1);
  75.     }
  76.  
  77.     infile2 = fopen(argv[1],"rb");
  78.  
  79.     if ((outfile = fopen(argv[2],"wb")) == NULL) {
  80.         printf ("Cannot open output file - %s\n");
  81.         exit(1);
  82.     }
  83.  
  84.     if (argc == 4){
  85.         /* Code segment supplied */
  86.         if (!sscanf(argv[3],"%x",&base_cs)){
  87.             printf("Invalid code segment - %s\n",argv[3]);
  88.             exit(1);
  89.         }
  90.     } else
  91.         base_cs = 0x10;
  92.  
  93.     /* Firstly process the headers of each file.  Read in the first */
  94.     /* block of the input (.EXE) file and use the information it    */
  95.     /* contains to construct the output (.LOD) file header.     */
  96.  
  97.     lod_hdr = (struct LODHDR *) out_buf;
  98.     exe_hdr = (struct EXEHDR *) in_buf;
  99.  
  100.     read_blk(infile,in_buf,32);
  101.  
  102.     if (exe_hdr->magic != EXE_MAGIC)
  103.     {
  104.         printf("Input file is not a valid .EXE file\n");
  105.         exit(1);
  106.     }
  107.  
  108.     rel_cnt = exe_hdr->nreloc;
  109.     printf("Relocation Count = %d\n",rel_cnt);
  110.  
  111.     lod_hdr->magic = LOD_MAGIC;
  112.     lod_hdr->version = LOD_VERSION;
  113.     lod_hdr->val_offset = exe_hdr->val_ip;
  114.     lod_hdr->val_seg = base_cs;
  115.  
  116.     if ((fd = open(argv[1],O_BINARY|O_RDONLY)) == -1){
  117.         printf("Can't get modification time for file - %s\n",argv[1]);
  118.         exit(1);
  119.     }
  120.     (void)getftime(fd,(struct ftime *)&lod_hdr->time_stamp);
  121.     close(fd);
  122.  
  123.     image_size = ((long) exe_hdr->npages * 512L) -
  124.              ((long) exe_hdr->hdrsize * 16L) -
  125.              (512L - (long)exe_hdr->nbytes );
  126.  
  127.     lod_hdr->image_size = image_size;
  128.  
  129.     printf("Load size = %05lx\n",image_size);
  130.  
  131.     /* Output the header to the .LOD file */
  132.  
  133.     write_blk(outfile,(char *)lod_hdr,sizeof(struct LODHDR));
  134.  
  135.     /* Seek input file over .EXE header   */
  136.  
  137.     if (fseek(infile,((long)exe_hdr->hdrsize * 16L),SEEK_SET) != 0){
  138.         printf("Seek error on .EXE Header\n");
  139.         exit(1);
  140.     }
  141.  
  142.     /* Position infile2 input stream to the first relocation item   */
  143.     
  144.     if (fseek(infile2, (long)exe_hdr->rel_offset, SEEK_SET) != 0) {
  145.         printf("Seek error on relocation items\n");
  146.         exit(1);
  147.     }
  148.  
  149.     printf("Reading relocation items.....\n");
  150.     
  151.     for (nrel = 0;nrel < rel_cnt;nrel++)
  152.         read_blk(infile2,(char *)&rel_table[nrel],sizeof(struct RELITEM));
  153.  
  154.     printf("Sorting relocation items.....\n");
  155.  
  156.     qsort((void *)rel_table,rel_cnt,sizeof(struct RELITEM),sort_rel);
  157.  
  158.     /* Copy across the image to the output file relocating as we go. */
  159.     position = 0;
  160.  
  161.     for (nrel = 0;nrel < rel_cnt;nrel++){
  162.         /* Process a relocation item */
  163.  
  164.         offset = (long)rel_table[nrel].offset +
  165.                    (16L * (long)rel_table[nrel].segment);
  166.  
  167.         /* Copy the input to the output until we reach the word
  168.          * to be relocated.
  169.          */
  170.  
  171.         while (position != offset){
  172.             if (offset - position > BUFSIZE)
  173.                 count = BUFSIZE;
  174.             else
  175.                 count = (unsigned) offset - position;
  176.  
  177.             read_blk(infile,in_buf,count);
  178.             write_blk(outfile,in_buf,count);
  179.             position += (long)count;    
  180.             image_size -= (long)count;
  181.         }
  182.  
  183.         /* Read the word to be relocated and..... relocate it ! */
  184.  
  185.         read_blk(infile,(char *)&i,2);
  186.  
  187.         i += base_cs;
  188.         write_blk(outfile,(char *)&i,2);
  189.         position += 2;
  190.         image_size -= 2;
  191.     }
  192.  
  193.     /* No more relocation items - copy the remainder of the input
  194.      * to the output and we're done.
  195.      */
  196.  
  197.     while (image_size) {
  198.         count = image_size > BUFSIZE ? BUFSIZE : (unsigned) image_size;
  199.         read_blk(infile,in_buf,count);
  200.         write_blk(outfile,in_buf,count);
  201.         image_size -= (long) count;
  202.     }
  203.  
  204.     exit(0);
  205. }
  206.  
  207. static void read_blk(fdesc,buffer,count)
  208. FILE *fdesc;
  209. char *buffer;
  210. int count;
  211. {
  212.     if (fread(buffer,count,1,fdesc) == 0){
  213.         printf("Unexpected EOF on input file\n");
  214.         exit(1);
  215.     }
  216. }
  217.  
  218.  
  219. static void write_blk(fdesc,buffer,count)
  220. FILE *fdesc;
  221. char *buffer;
  222. int count;
  223. {
  224.     if (fwrite(buffer,count,1,fdesc) == 0){
  225.         printf("Error on writing output file\n");
  226.         exit(1);
  227.     }
  228. }
  229.  
  230. int sort_rel(const void *a,const void *b)
  231. {
  232.     long *x = (long *)a;
  233.     long *y = (long *)b;
  234.  
  235.     if (*x == *y) return (0);
  236.  
  237.     return (*x > *y ? 1 : -1);
  238. }
  239.